use crate::src::test::framework::{run_tests};
use crate::src::src::hash_int::{int_hash};
use crate::src::test::alloc_testing::{alloc_test_strdup, alloc_test_get_allocated, alloc_test_set_limit, alloc_test_malloc, alloc_test_free};
use crate::src::src::compare_string::{string_equal};
use crate::src::src::hash_table::{hash_table_iter_next, hash_table_lookup, hash_table_num_entries, hash_table_insert, hash_table_register_free_functions, hash_table_remove, hash_table_iterate, hash_table_new, hash_table_free, hash_table_iter_has_more};
use crate::src::src::hash_string::{string_hash};
use crate::src::src::compare_int::{int_equal};
use crate::src::struct_and_type::{HashTableValueFreeFunc, HashTableKey, HashTablePair, size_t, HashTableValue, HashTableHashFunc, HashTableEqualFunc, HashTable, _HashTable, HashTableIterator, HashTableKeyFreeFunc, _HashTablePair, _HashTableIterator, _HashTableEntry, HashTableEntry, UnitTestFunction};
use ::libc;
extern "C" {
    
    
    fn sprintf(_: *mut libc::c_char, _: *const libc::c_char, _: ...) -> libc::c_int;
    fn atoi(__nptr: *const libc::c_char) -> libc::c_int;
    fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
}
#[no_mangle]
pub static mut value1: libc::c_int = 1 as libc::c_int;
#[no_mangle]
pub static mut value2: libc::c_int = 2 as libc::c_int;
#[no_mangle]
pub static mut value3: libc::c_int = 3 as libc::c_int;
#[no_mangle]
pub static mut value4: libc::c_int = 4 as libc::c_int;
#[no_mangle]
pub static mut allocated_keys: libc::c_int = 0 as libc::c_int;
#[no_mangle]
pub static mut allocated_values_test_hash_table: libc::c_int = 0 as libc::c_int;
#[no_mangle]
pub unsafe extern "C" fn generate_hash_table() -> *mut HashTable {
    let mut hash_table: *mut HashTable = 0 as *mut HashTable;
    let mut buf: [libc::c_char; 10] = [0; 10];
    let mut value: *mut libc::c_char = 0 as *mut libc::c_char;
    let mut i: libc::c_int = 0;
    hash_table = hash_table_new(
        Some(string_hash as unsafe extern "C" fn(*mut libc::c_void) -> libc::c_uint),
        Some(
            string_equal
                as unsafe extern "C" fn(
                    *mut libc::c_void,
                    *mut libc::c_void,
                ) -> libc::c_int,
        ),
    );
    i = 0 as libc::c_int;
    while i < 10000 as libc::c_int {
        sprintf(buf.as_mut_ptr(), b"%i\0" as *const u8 as *const libc::c_char, i);
        value = alloc_test_strdup(buf.as_mut_ptr());
        hash_table_insert(hash_table, value as HashTableKey, value as HashTableValue);
        i += 1;
        i;
    }
    hash_table_register_free_functions(
        hash_table,
        None,
        Some(alloc_test_free as unsafe extern "C" fn(*mut libc::c_void) -> ()),
    );
    return hash_table;
}
#[no_mangle]
pub unsafe extern "C" fn test_hash_table_new_free() {
    let mut hash_table: *mut HashTable = 0 as *mut HashTable;
    hash_table = hash_table_new(
        Some(int_hash as unsafe extern "C" fn(*mut libc::c_void) -> libc::c_uint),
        Some(
            int_equal
                as unsafe extern "C" fn(
                    *mut libc::c_void,
                    *mut libc::c_void,
                ) -> libc::c_int,
        ),
    );
    assert!(!hash_table.is_null());
    hash_table_insert(
        hash_table,
        &mut value1 as *mut libc::c_int as HashTableKey,
        &mut value1 as *mut libc::c_int as HashTableValue,
    );
    hash_table_insert(
        hash_table,
        &mut value2 as *mut libc::c_int as HashTableKey,
        &mut value2 as *mut libc::c_int as HashTableValue,
    );
    hash_table_insert(
        hash_table,
        &mut value3 as *mut libc::c_int as HashTableKey,
        &mut value3 as *mut libc::c_int as HashTableValue,
    );
    hash_table_insert(
        hash_table,
        &mut value4 as *mut libc::c_int as HashTableKey,
        &mut value4 as *mut libc::c_int as HashTableValue,
    );
    hash_table_free(hash_table);
    alloc_test_set_limit(0 as libc::c_int);
    hash_table = hash_table_new(
        Some(int_hash as unsafe extern "C" fn(*mut libc::c_void) -> libc::c_uint),
        Some(
            int_equal
                as unsafe extern "C" fn(
                    *mut libc::c_void,
                    *mut libc::c_void,
                ) -> libc::c_int,
        ),
    );
    assert!(hash_table.is_null());
    assert!(alloc_test_get_allocated() == 0 as libc::c_int as libc::c_ulong);
    alloc_test_set_limit(1 as libc::c_int);
    hash_table = hash_table_new(
        Some(int_hash as unsafe extern "C" fn(*mut libc::c_void) -> libc::c_uint),
        Some(
            int_equal
                as unsafe extern "C" fn(
                    *mut libc::c_void,
                    *mut libc::c_void,
                ) -> libc::c_int,
        ),
    );
    assert!(hash_table.is_null());
    assert!(alloc_test_get_allocated() == 0 as libc::c_int as libc::c_ulong);
}
#[no_mangle]
pub unsafe extern "C" fn test_hash_table_insert_lookup() {
    let mut hash_table: *mut HashTable = 0 as *mut HashTable;
    let mut buf: [libc::c_char; 10] = [0; 10];
    let mut value: *mut libc::c_char = 0 as *mut libc::c_char;
    let mut i: libc::c_int = 0;
    hash_table = generate_hash_table();
    assert!(hash_table_num_entries(hash_table) == 10000 as libc::c_int as libc::c_uint);
    i = 0 as libc::c_int;
    while i < 10000 as libc::c_int {
        sprintf(buf.as_mut_ptr(), b"%i\0" as *const u8 as *const libc::c_char, i);
        value = hash_table_lookup(hash_table, buf.as_mut_ptr() as HashTableKey)
            as *mut libc::c_char;
        assert!(strcmp(value, buf.as_mut_ptr()) == 0 as libc::c_int);
        i += 1;
        i;
    }
    sprintf(
        buf.as_mut_ptr(),
        b"%i\0" as *const u8 as *const libc::c_char,
        -(1 as libc::c_int),
    );
    assert!((hash_table_lookup(hash_table, buf.as_mut_ptr() as HashTableKey)).is_null());
    sprintf(
        buf.as_mut_ptr(),
        b"%i\0" as *const u8 as *const libc::c_char,
        10000 as libc::c_int,
    );
    assert!((hash_table_lookup(hash_table, buf.as_mut_ptr() as HashTableKey)).is_null());
    sprintf(
        buf.as_mut_ptr(),
        b"%i\0" as *const u8 as *const libc::c_char,
        12345 as libc::c_int,
    );
    hash_table_insert(
        hash_table,
        buf.as_mut_ptr() as HashTableKey,
        alloc_test_strdup(b"hello world\0" as *const u8 as *const libc::c_char)
            as HashTableValue,
    );
    value = hash_table_lookup(hash_table, buf.as_mut_ptr() as HashTableKey)
        as *mut libc::c_char;
    assert!(strcmp(value, b"hello world\0" as *const u8 as *const libc::c_char)
        == 0 as libc::c_int);
    hash_table_free(hash_table);
}
#[no_mangle]
pub unsafe extern "C" fn test_hash_table_remove() {
    let mut hash_table: *mut HashTable = 0 as *mut HashTable;
    let mut buf: [libc::c_char; 10] = [0; 10];
    hash_table = generate_hash_table();
    assert!(hash_table_num_entries(hash_table) == 10000 as libc::c_int as libc::c_uint);
    sprintf(
        buf.as_mut_ptr(),
        b"%i\0" as *const u8 as *const libc::c_char,
        5000 as libc::c_int,
    );
    assert!(!(hash_table_lookup(hash_table, buf.as_mut_ptr() as HashTableKey)).is_null());
    hash_table_remove(hash_table, buf.as_mut_ptr() as HashTableKey);
    assert!(hash_table_num_entries(hash_table) == 9999 as libc::c_int as libc::c_uint);
    assert!((hash_table_lookup(hash_table, buf.as_mut_ptr() as HashTableKey)).is_null());
    sprintf(
        buf.as_mut_ptr(),
        b"%i\0" as *const u8 as *const libc::c_char,
        -(1 as libc::c_int),
    );
    hash_table_remove(hash_table, buf.as_mut_ptr() as HashTableKey);
    assert!(hash_table_num_entries(hash_table) == 9999 as libc::c_int as libc::c_uint);
    hash_table_free(hash_table);
}
#[no_mangle]
pub unsafe extern "C" fn test_hash_table_iterating() {
    let mut hash_table: *mut HashTable = 0 as *mut HashTable;
    let mut iterator: HashTableIterator = HashTableIterator {
        hash_table: 0 as *mut HashTable,
        next_entry: 0 as *mut HashTableEntry,
        next_chain: 0,
    };
    let mut count: libc::c_int = 0;
    hash_table = generate_hash_table();
    count = 0 as libc::c_int;
    hash_table_iterate(hash_table, &mut iterator);
    while hash_table_iter_has_more(&mut iterator) != 0 {
        hash_table_iter_next(&mut iterator);
        count += 1;
        count;
    }
    assert!(count == 10000 as libc::c_int);
    let mut pair: HashTablePair = hash_table_iter_next(&mut iterator);
    assert!((pair.value).is_null());
    hash_table_free(hash_table);
    hash_table = hash_table_new(
        Some(int_hash as unsafe extern "C" fn(*mut libc::c_void) -> libc::c_uint),
        Some(
            int_equal
                as unsafe extern "C" fn(
                    *mut libc::c_void,
                    *mut libc::c_void,
                ) -> libc::c_int,
        ),
    );
    hash_table_iterate(hash_table, &mut iterator);
    assert!(hash_table_iter_has_more(&mut iterator) == 0 as libc::c_int);
    hash_table_free(hash_table);
}
#[no_mangle]
pub unsafe extern "C" fn test_hash_table_iterating_remove() {
    let mut hash_table: *mut HashTable = 0 as *mut HashTable;
    let mut iterator: HashTableIterator = HashTableIterator {
        hash_table: 0 as *mut HashTable,
        next_entry: 0 as *mut HashTableEntry,
        next_chain: 0,
    };
    let mut buf: [libc::c_char; 10] = [0; 10];
    let mut val: *mut libc::c_char = 0 as *mut libc::c_char;
    let mut pair: HashTablePair = HashTablePair {
        key: 0 as *mut libc::c_void,
        value: 0 as *mut libc::c_void,
    };
    let mut count: libc::c_int = 0;
    let mut removed: libc::c_uint = 0;
    let mut i: libc::c_int = 0;
    hash_table = generate_hash_table();
    count = 0 as libc::c_int;
    removed = 0 as libc::c_int as libc::c_uint;
    hash_table_iterate(hash_table, &mut iterator);
    while hash_table_iter_has_more(&mut iterator) != 0 {
        pair = hash_table_iter_next(&mut iterator);
        val = pair.value as *mut libc::c_char;
        if atoi(val) % 100 as libc::c_int == 0 as libc::c_int {
            hash_table_remove(hash_table, val as HashTableKey);
            removed = removed.wrapping_add(1);
            removed;
        }
        count += 1;
        count;
    }
    assert!(removed == 100 as libc::c_int as libc::c_uint);
    assert!(count == 10000 as libc::c_int);
    assert!(hash_table_num_entries(hash_table)
        == (10000 as libc::c_int as libc::c_uint).wrapping_sub(removed));
    i = 0 as libc::c_int;
    while i < 10000 as libc::c_int {
        sprintf(buf.as_mut_ptr(), b"%i\0" as *const u8 as *const libc::c_char, i);
        if i % 100 as libc::c_int == 0 as libc::c_int {
            assert!((hash_table_lookup(hash_table, buf.as_mut_ptr() as HashTableKey))
                .is_null());
        } else {
            assert!(!(hash_table_lookup(hash_table, buf.as_mut_ptr() as HashTableKey))
                .is_null());
        }
        i += 1;
        i;
    }
    hash_table_free(hash_table);
}
#[no_mangle]
pub unsafe extern "C" fn new_key(mut value: libc::c_int) -> *mut libc::c_int {
    let mut result: *mut libc::c_int = 0 as *mut libc::c_int;
    result = alloc_test_malloc(::core::mem::size_of::<libc::c_int>() as libc::c_ulong)
        as *mut libc::c_int;
    *result = value;
    allocated_keys += 1;
    allocated_keys;
    return result;
}
#[no_mangle]
pub unsafe extern "C" fn free_key(mut key: *mut libc::c_void) {
    alloc_test_free(key);
    allocated_keys -= 1;
    allocated_keys;
}
#[no_mangle]
pub unsafe extern "C" fn new_value_test_hash_table(mut value: libc::c_int) -> *mut libc::c_int {
    let mut result: *mut libc::c_int = 0 as *mut libc::c_int;
    result = alloc_test_malloc(::core::mem::size_of::<libc::c_int>() as libc::c_ulong)
        as *mut libc::c_int;
    *result = value;
    allocated_values_test_hash_table += 1;
    allocated_values_test_hash_table;
    return result;
}
#[no_mangle]
pub unsafe extern "C" fn free_value_test_hash_table(mut value: *mut libc::c_void) {
    alloc_test_free(value);
    allocated_values_test_hash_table -= 1;
    allocated_values_test_hash_table;
}
#[no_mangle]
pub unsafe extern "C" fn test_hash_table_free_functions() {
    let mut hash_table: *mut HashTable = 0 as *mut HashTable;
    let mut key: *mut libc::c_int = 0 as *mut libc::c_int;
    let mut value: *mut libc::c_int = 0 as *mut libc::c_int;
    let mut i: libc::c_int = 0;
    hash_table = hash_table_new(
        Some(int_hash as unsafe extern "C" fn(*mut libc::c_void) -> libc::c_uint),
        Some(
            int_equal
                as unsafe extern "C" fn(
                    *mut libc::c_void,
                    *mut libc::c_void,
                ) -> libc::c_int,
        ),
    );
    hash_table_register_free_functions(
        hash_table,
        Some(free_key as unsafe extern "C" fn(*mut libc::c_void) -> ()),
        Some(free_value_test_hash_table as unsafe extern "C" fn(*mut libc::c_void) -> ()),
    );
    allocated_values_test_hash_table = 0 as libc::c_int;
    i = 0 as libc::c_int;
    while i < 10000 as libc::c_int {
        key = new_key(i);
        value = new_value_test_hash_table(99 as libc::c_int);
        hash_table_insert(hash_table, key as HashTableKey, value as HashTableValue);
        i += 1;
        i;
    }
    assert!(allocated_keys == 10000 as libc::c_int);
    assert!(allocated_values_test_hash_table == 10000 as libc::c_int);
    i = 10000 as libc::c_int / 2 as libc::c_int;
    hash_table_remove(hash_table, &mut i as *mut libc::c_int as HashTableKey);
    assert!(allocated_keys == 10000 as libc::c_int - 1 as libc::c_int);
    assert!(allocated_values_test_hash_table == 10000 as libc::c_int - 1 as libc::c_int);
    key = new_key(10000 as libc::c_int / 3 as libc::c_int);
    value = new_value_test_hash_table(999 as libc::c_int);
    assert!(allocated_keys == 10000 as libc::c_int);
    assert!(allocated_values_test_hash_table == 10000 as libc::c_int);
    hash_table_insert(hash_table, key as HashTableKey, value as HashTableValue);
    assert!(allocated_keys == 10000 as libc::c_int - 1 as libc::c_int);
    assert!(allocated_values_test_hash_table == 10000 as libc::c_int - 1 as libc::c_int);
    hash_table_free(hash_table);
    assert!(allocated_keys == 0 as libc::c_int);
    assert!(allocated_values_test_hash_table == 0 as libc::c_int);
}
#[no_mangle]
pub unsafe extern "C" fn test_hash_table_out_of_memory() {
    let mut hash_table: *mut HashTable = 0 as *mut HashTable;
    let mut values: [libc::c_int; 66] = [0; 66];
    let mut i: libc::c_uint = 0;
    hash_table = hash_table_new(
        Some(int_hash as unsafe extern "C" fn(*mut libc::c_void) -> libc::c_uint),
        Some(
            int_equal
                as unsafe extern "C" fn(
                    *mut libc::c_void,
                    *mut libc::c_void,
                ) -> libc::c_int,
        ),
    );
    alloc_test_set_limit(0 as libc::c_int);
    values[0 as libc::c_int as usize] = 0 as libc::c_int;
    assert!(hash_table_insert(
        hash_table,
        &mut *values.as_mut_ptr().offset(0 as libc::c_int as isize) as *mut libc::c_int
            as HashTableKey,
        &mut *values.as_mut_ptr().offset(0 as libc::c_int as isize) as *mut libc::c_int
            as HashTableValue,
    ) == 0 as libc::c_int);
    assert!(hash_table_num_entries(hash_table) == 0 as libc::c_int as libc::c_uint);
    alloc_test_set_limit(-(1 as libc::c_int));
    i = 0 as libc::c_int as libc::c_uint;
    while i < 65 as libc::c_int as libc::c_uint {
        values[i as usize] = i as libc::c_int;
        assert!(hash_table_insert(
            hash_table,
            &mut *values.as_mut_ptr().offset(i as isize) as *mut libc::c_int
                as HashTableKey,
            &mut *values.as_mut_ptr().offset(i as isize) as *mut libc::c_int
                as HashTableValue,
        ) != 0 as libc::c_int);
        assert!(hash_table_num_entries(hash_table)
            == i.wrapping_add(1 as libc::c_int as libc::c_uint));
        i = i.wrapping_add(1);
        i;
    }
    assert!(hash_table_num_entries(hash_table) == 65 as libc::c_int as libc::c_uint);
    alloc_test_set_limit(0 as libc::c_int);
    values[65 as libc::c_int as usize] = 65 as libc::c_int;
    assert!(hash_table_insert(
        hash_table,
        &mut *values.as_mut_ptr().offset(65 as libc::c_int as isize) as *mut libc::c_int
            as HashTableKey,
        &mut *values.as_mut_ptr().offset(65 as libc::c_int as isize) as *mut libc::c_int
            as HashTableValue,
    ) == 0 as libc::c_int);
    assert!(hash_table_num_entries(hash_table) == 65 as libc::c_int as libc::c_uint);
    hash_table_free(hash_table);
}
#[no_mangle]
pub unsafe extern "C" fn test_hash_iterator_key_pair() {
    let mut hash_table: *mut HashTable = 0 as *mut HashTable;
    let mut iterator: HashTableIterator = HashTableIterator {
        hash_table: 0 as *mut HashTable,
        next_entry: 0 as *mut HashTableEntry,
        next_chain: 0,
    };
    let mut pair: HashTablePair = HashTablePair {
        key: 0 as *mut libc::c_void,
        value: 0 as *mut libc::c_void,
    };
    hash_table = hash_table_new(
        Some(int_hash as unsafe extern "C" fn(*mut libc::c_void) -> libc::c_uint),
        Some(
            int_equal
                as unsafe extern "C" fn(
                    *mut libc::c_void,
                    *mut libc::c_void,
                ) -> libc::c_int,
        ),
    );
    hash_table_insert(
        hash_table,
        &mut value1 as *mut libc::c_int as HashTableKey,
        &mut value1 as *mut libc::c_int as HashTableValue,
    );
    hash_table_insert(
        hash_table,
        &mut value2 as *mut libc::c_int as HashTableKey,
        &mut value2 as *mut libc::c_int as HashTableValue,
    );
    hash_table_iterate(hash_table, &mut iterator);
    while hash_table_iter_has_more(&mut iterator) != 0 {
        pair = hash_table_iter_next(&mut iterator);
        let mut key: *mut libc::c_int = pair.key as *mut libc::c_int;
        let mut val: *mut libc::c_int = pair.value as *mut libc::c_int;
        assert!(*key == *val);
    }
    hash_table_free(hash_table);
}
static mut tests_test_hash_table: [UnitTestFunction; 9] = unsafe {
    [
        Some(test_hash_table_new_free as unsafe extern "C" fn() -> ()),
        Some(test_hash_table_insert_lookup as unsafe extern "C" fn() -> ()),
        Some(test_hash_table_remove as unsafe extern "C" fn() -> ()),
        Some(test_hash_table_iterating as unsafe extern "C" fn() -> ()),
        Some(test_hash_table_iterating_remove as unsafe extern "C" fn() -> ()),
        Some(test_hash_table_free_functions as unsafe extern "C" fn() -> ()),
        Some(test_hash_table_out_of_memory as unsafe extern "C" fn() -> ()),
        ::core::mem::transmute::<
            Option::<unsafe extern "C" fn() -> ()>,
            UnitTestFunction,
        >(
            Some(
                ::core::mem::transmute::<
                    unsafe extern "C" fn() -> (),
                    unsafe extern "C" fn() -> (),
                >(test_hash_iterator_key_pair),
            ),
        ),
        None,
    ]
};
unsafe fn main_0_test_hash_table(
    mut argc: libc::c_int,
    mut argv: *mut *mut libc::c_char,
) -> libc::c_int {
    run_tests(tests_test_hash_table.as_mut_ptr());
    return 0 as libc::c_int;
}
pub fn main_test_hash_table() {
    let mut args: Vec::<*mut libc::c_char> = Vec::new();
    for arg in ::std::env::args() {
        args.push(
            (::std::ffi::CString::new(arg))
                .expect("Failed to convert argument into CString.")
                .into_raw(),
        );
    }
    args.push(::core::ptr::null_mut());
    unsafe {
        ::std::process::exit(
            main_0_test_hash_table(
                (args.len() - 1) as libc::c_int,
                args.as_mut_ptr() as *mut *mut libc::c_char,
            ) as i32,
        )
    }
}
